// Copyright (C) joyinter
// All rights reserved.
// 
// Author : deng xinguo
// Date   : 2005-5-08

#ifndef __CS_GAMEDLL_H_
#define __CS_GAMEDLL_H_


#include "stdafx.h"
#include "detours.h"
#include <sstream>
#include <vector>
#include "EnvironmentInfo.h"
#include "SockManager.h"
#include "log.h"
#include "Ws2spi.h"
#include  "Mswsock.h"
#include "winsock2.h"

using namespace std;

int g_iWinVersion; 

int GetWindowsVersion()
{
	OSVERSIONINFOEX osvi;
   BOOL bOsVersionInfoEx;

   // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
   // If that fails, try using the OSVERSIONINFO structure.

   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

   if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
   {
      osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
      if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) 
         return -1;
   }

   switch (osvi.dwPlatformId)
   {
      // Test for the Windows NT product family.
      case VER_PLATFORM_WIN32_NT:

         // Test for the specific product family.
         if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
            
			 return 2003;

         if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
            
			 return 2002;//xp

         if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
           return 2000;

         if ( osvi.dwMajorVersion <= 4 )
           return 1999;//nt

    
      // Test for the Windows 95 product family.
      case VER_PLATFORM_WIN32_WINDOWS:

         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
         {
              return 1995;
         } 

         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
         {
            return 1998;
         } 

         if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
         {
            
         } 
         break;

      case VER_PLATFORM_WIN32s:

         
         break;
   }
   return 0;
}

void setWinVersionHooked()
{
	
	g_iWinVersion=GetWindowsVersion();
	
	if (g_iWinVersion>1998)
	{
		
       #define   WIN_VER_UP98
	}
}

#   pragma comment(lib, "ws2_32.lib")

#   pragma comment(lib, "wsock32.lib")




HANDLE hPipeWr;

#include <conio.h>

DETOUR_TRAMPOLINE(BOOL
    WINAPI
    Real_WriteConsoleA(
        IN HANDLE hConsoleOutput,
        IN CONST VOID *lpBuffer,
        IN DWORD nNumberOfCharsToWrite,
        OUT LPDWORD lpNumberOfCharsWritten,
        IN LPVOID lpReserved
        ),

                  WriteConsoleA);

extern "C"
{
	BOOL WINAPI Mine_WriteConsoleA(
        IN HANDLE hConsoleOutput,
        IN CONST VOID *lpBuffer,
        IN DWORD nNumberOfCharsToWrite,
        OUT LPDWORD lpNumberOfCharsWritten,
        IN LPVOID lpReserved
        );


}

BOOL WINAPI Mine_WriteConsoleA(
        IN HANDLE hConsoleOutput,
        IN CONST VOID *lpBuffer,
        IN DWORD nNumberOfCharsToWrite,
        OUT LPDWORD lpNumberOfCharsWritten,
        IN LPVOID lpReserved
        )
{
	DWORD dwWrite;
	WriteFile(hPipeWr, (LPCSTR)lpBuffer, nNumberOfCharsToWrite, &dwWrite, NULL);

    return Real_WriteConsoleA(
        hConsoleOutput,
        lpBuffer,
        nNumberOfCharsToWrite,
        lpNumberOfCharsWritten,
        lpReserved);
}

DETOUR_TRAMPOLINE(BOOL WINAPI Real_CreateProcessA( LPCSTR lpApplicationName,
				                                   LPSTR lpCommandLine,
											       LPSECURITY_ATTRIBUTES lpProcessAttributes,
											       LPSECURITY_ATTRIBUTES lpThreadAttributes,
											       BOOL bInheritHandles,
											       DWORD dwCreationFlags,
											       LPVOID lpEnvironment,
											       LPCSTR lpCurrentDirectory,
											       LPSTARTUPINFOA lpStartupInfo,
											       LPPROCESS_INFORMATION lpProcessInformation),

											       CreateProcessA);


DETOUR_TRAMPOLINE(int WINAPI Real_WSASend(SOCKET hSocket,
                                             LPWSABUF buf,
                                             DWORD iLen,
                                             LPDWORD a3,
                                             DWORD a4,
                                             LPWSAOVERLAPPED a5,
                                             LPWSAOVERLAPPED_COMPLETION_ROUTINE a6),
                  WSASend);

DETOUR_TRAMPOLINE(int WINAPI Real_WSARecv(SOCKET hSocket,
                                             LPWSABUF buf,
                                             DWORD iLen,
                                             LPDWORD a3,
                                             LPDWORD a4,
                                             LPWSAOVERLAPPED a5,
                                             LPWSAOVERLAPPED_COMPLETION_ROUTINE a6),
                  WSARecv);

DETOUR_TRAMPOLINE(int WINAPI Real_WSASendTo(SOCKET hSocket,
                                               LPWSABUF buf,
                                               DWORD iLen,
                                               LPDWORD a3,
                                               DWORD a4,
                                               sockaddr* a5,
                                               int a6,
                                               LPWSAOVERLAPPED a7,
                                               LPWSAOVERLAPPED_COMPLETION_ROUTINE a8),
                  WSASendTo);

DETOUR_TRAMPOLINE(int WINAPI Real_WSARecvFrom(SOCKET hSocket,
                                                 LPWSABUF buf,
                                                 DWORD iLen,
                                                 LPDWORD a3,
                                                 LPDWORD a4,
                                                 sockaddr* a5,
                                                 LPINT a6,
                                                 LPWSAOVERLAPPED a7,
                                                 LPWSAOVERLAPPED_COMPLETION_ROUTINE a8),
                  WSARecvFrom);
DETOUR_TRAMPOLINE(int WINAPI Real_WSAAccept(  SOCKET s,
												struct sockaddr* addr,
												LPINT addrlen,
												LPCONDITIONPROC lpfnCondition,
												DWORD dwCallbackData),
                  WSAAccept);
DETOUR_TRAMPOLINE(struct hostent* FAR  WINAPI Real_gethostbyname( const char* name
),
                  gethostbyname);

DETOUR_TRAMPOLINE(int WINAPI Real_WSACleanup(),
                  WSACleanup);
DETOUR_TRAMPOLINE(int WINAPI Real_WSAStartup(
				   WORD wVersionRequested,
					LPWSADATA lpWSAData
				  ),
                  WSAStartup);


DETOUR_TRAMPOLINE(int WINAPI Real_recv(SOCKET hSocket,
                                          char* sBuff,
                                          int iLen,
                                          int a3),
                  recv);

DETOUR_TRAMPOLINE(int WINAPI Real_recvfrom(SOCKET hSocket,
                                              char* sBuff,
                                              int iLen,
                                              int a3,
                                              sockaddr* a4,
                                              int* a5),
                  recvfrom);

DETOUR_TRAMPOLINE(int WINAPI Real_send(SOCKET hSocket,
                                          char* sBuff,
                                          int iLen,
                                          int a3),
                  send);

DETOUR_TRAMPOLINE(int WINAPI Real_sendto(SOCKET hSocket,
                                            char* sBuff,
                                            int iLen,
                                            int a3,
                                            sockaddr* a4,
                                            int a5),
                  sendto);
DETOUR_TRAMPOLINE(int WINAPI  Real_connect(SOCKET s,
										 const struct sockaddr* name,
										 int namelen),
                  connect);
DETOUR_TRAMPOLINE(SOCKET WINAPI Real_accept(SOCKET s,
										   struct sockaddr* addr,
										   int* addrlen),
                  accept);
DETOUR_TRAMPOLINE(int WINAPI Real_getpeername( SOCKET s,
											struct sockaddr* name,
											int* namelen),
                  getpeername);


DETOUR_TRAMPOLINE(int WINAPI Real_bind(SOCKET s,
										   const struct sockaddr* addr,
										   int addrlen),
                  bind);

DETOUR_TRAMPOLINE(int WINAPI Real_closesocket(SOCKET s),
                  closesocket);
DETOUR_TRAMPOLINE(int WINAPI Real_getsockname(SOCKET s,
										   struct sockaddr* addr,
										   int* addrlen),
				  getsockname);
DETOUR_TRAMPOLINE(int WINAPI Real_ioctlsocket(SOCKET s,
										    long cmd,
											u_long* argp),
                  ioctlsocket);
DETOUR_TRAMPOLINE(int WINAPI Real_setsockopt(SOCKET s,
										   int level,
											int optname,
											const char* optval,
											int optlen),
                  setsockopt);
DETOUR_TRAMPOLINE(int WINAPI Real_listen(SOCKET s,
										   	int backlog),
                  listen);

#endif//__CS_GAMEDLL_H_